<!DOCTYPE html>
<html>
<head>
<title>vue特有.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">

<style>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

body {
	font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
	font-size: 14px;
	padding: 0 12px;
	line-height: 22px;
	word-wrap: break-word;
}

#code-csp-warning {
	position: fixed;
	top: 0;
	right: 0;
	color: white;
	margin: 16px;
	text-align: center;
	font-size: 12px;
	font-family: sans-serif;
	background-color:#444444;
	cursor: pointer;
	padding: 6px;
	box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}

#code-csp-warning:hover {
	text-decoration: none;
	background-color:#007acc;
	box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}


body.scrollBeyondLastLine {
	margin-bottom: calc(100vh - 22px);
}

body.showEditorSelection .code-line {
	position: relative;
}

body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
	content: "";
	display: block;
	position: absolute;
	top: 0;
	left: -12px;
	height: 100%;
}

body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
	left: -30px;
}

.vscode-light.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(0, 0, 0, 0.15);
}

.vscode-light.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(0, 0, 0, 0.40);
}

.vscode-dark.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 255, 255, 0.4);
}

.vscode-dark.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 255, 255, 0.60);
}

.vscode-high-contrast.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 160, 0, 0.7);
}

.vscode-high-contrast.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 160, 0, 1);
}

img {
	max-width: 100%;
	max-height: 100%;
}

a {
	color: #4080D0;
	text-decoration: none;
}

a:focus,
input:focus,
select:focus,
textarea:focus {
	outline: 1px solid -webkit-focus-ring-color;
	outline-offset: -1px;
}

hr {
	border: 0;
	height: 2px;
	border-bottom: 2px solid;
}

h1 {
	padding-bottom: 0.3em;
	line-height: 1.2;
	border-bottom-width: 1px;
	border-bottom-style: solid;
}

h1, h2, h3 {
	font-weight: normal;
}

h1 code,
h2 code,
h3 code,
h4 code,
h5 code,
h6 code {
	font-size: inherit;
	line-height: auto;
}

a:hover {
	color: #4080D0;
	text-decoration: underline;
}

table {
	border-collapse: collapse;
}

table > thead > tr > th {
	text-align: left;
	border-bottom: 1px solid;
}

table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
	padding: 5px 10px;
}

table > tbody > tr + tr > td {
	border-top: 1px solid;
}

blockquote {
	margin: 0 7px 0 5px;
	padding: 0 16px 0 10px;
	border-left: 5px solid;
}

code {
	font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
	font-size: 14px;
	line-height: 19px;
}

body.wordWrap pre {
	white-space: pre-wrap;
}

.mac code {
	font-size: 12px;
	line-height: 18px;
}

pre:not(.hljs),
pre.hljs code > div {
	padding: 16px;
	border-radius: 3px;
	overflow: auto;
}

/** Theming */

.vscode-light,
.vscode-light pre code {
	color: rgb(30, 30, 30);
}

.vscode-dark,
.vscode-dark pre code {
	color: #DDD;
}

.vscode-high-contrast,
.vscode-high-contrast pre code {
	color: white;
}

.vscode-light code {
	color: #A31515;
}

.vscode-dark code {
	color: #D7BA7D;
}

.vscode-light pre:not(.hljs),
.vscode-light code > div {
	background-color: rgba(220, 220, 220, 0.4);
}

.vscode-dark pre:not(.hljs),
.vscode-dark code > div {
	background-color: rgba(10, 10, 10, 0.4);
}

.vscode-high-contrast pre:not(.hljs),
.vscode-high-contrast code > div {
	background-color: rgb(0, 0, 0);
}

.vscode-high-contrast h1 {
	border-color: rgb(0, 0, 0);
}

.vscode-light table > thead > tr > th {
	border-color: rgba(0, 0, 0, 0.69);
}

.vscode-dark table > thead > tr > th {
	border-color: rgba(255, 255, 255, 0.69);
}

.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
	border-color: rgba(0, 0, 0, 0.18);
}

.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
	border-color: rgba(255, 255, 255, 0.18);
}

.vscode-light blockquote,
.vscode-dark blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.vscode-high-contrast blockquote {
	background: transparent;
	border-color: #fff;
}
</style>

<style>
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */

/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
	color: #8e908c;
}

/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
	color: #c82829;
}

/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
	color: #f5871f;
}

/* Tomorrow Yellow */
.hljs-attribute {
	color: #eab700;
}

/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
	color: #718c00;
}

/* Tomorrow Blue */
.hljs-title,
.hljs-section {
	color: #4271ae;
}

/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
	color: #8959a8;
}

.hljs {
	display: block;
	overflow-x: auto;
	color: #4d4d4c;
	padding: 0.5em;
}

.hljs-emphasis {
	font-style: italic;
}

.hljs-strong {
	font-weight: bold;
}
</style>

<style>
/*
 * Markdown PDF CSS
 */

 body {
	font-family:  "Meiryo", "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
}

pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	border-radius: 3px;
	overflow-x: auto;
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

pre:not(.hljs) {
	padding: 23px;
	line-height: 19px;
}

blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.emoji {
	height: 1.4em;
}

/* for inline code */
:not(pre):not(.hljs) > code {
	color: #C9AE75; /* Change the old color so it seems less like an error */
	font-size: inherit;
}

/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
	page-break-after: always;
}

</style>

</head>
<body>
<h1 id="%E8%99%9A%E6%8B%9F-dom">虚拟 DOM</h1>
<ol>
<li>使用到 ES5 里的 object.defineproperties 订阅数据变化 故支持 ie9+</li>
</ol>
<h1 id="%E7%BB%93%E6%9E%84">结构</h1>
<pre class="hljs"><code><div><span class="hljs-meta">&lt;!DOCTYPE html&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Vue 测试实例 - 菜鸟教程(runoob.com)<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.staticfile.org/vue/2.4.2/vue.min.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
	
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  	<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ message }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
	<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>  <span class="hljs-attr">v-model</span>=<span class="hljs-string">"message"</span>  /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="actionscript">
<span class="hljs-keyword">new</span> Vue({
  el: <span class="hljs-string">'#app'</span>,
  data: {
    message: <span class="hljs-string">'Hello Vue.js!'</span>
  }
})
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</div></code></pre>
<h2 id="%E6%89%80%E6%9C%89%E8%83%BD%E5%9C%A8%E6%A8%A1%E6%9D%BF%E9%87%8C%E5%87%BA%E7%8E%B0%E7%9A%84">所有能在模板里出现的</h2>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  	<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ message }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>  <span class="hljs-attr">v-model</span>=<span class="hljs-string">"one_count"</span>  /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>getName:{{ getName() }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>one_count:{{ one_count }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>two_count:{{ two_count }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>total:{{ total }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>:<span class="hljs-string">'#app'</span>,
  <span class="hljs-attr">data</span>:{
    <span class="hljs-attr">msg</span>:<span class="hljs-string">'aaa'</span>,
    <span class="hljs-attr">one_count</span>:<span class="hljs-number">1</span>,
    <span class="hljs-attr">two_count</span>:<span class="hljs-number">2</span>
  },
  <span class="hljs-attr">methods</span>:{
    <span class="hljs-attr">getName</span>:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
      <span class="hljs-keyword">return</span> <span class="hljs-string">'abc'</span>;
    }
  },
  <span class="hljs-attr">computed</span>:{
    <span class="hljs-attr">total</span>:one_count+two_count;
  }
});
</div></code></pre>
<blockquote>
<p>data对象<br>
methods<br>
computed
props</p>
</blockquote>
<h3 id="computed-%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7">computed  计算属性</h3>
<h3 id="computed%E4%B8%8Emethods%E7%9A%84%E5%8C%BA%E5%88%AB">computed与methods的区别</h3>
<ol>
<li>computed 必须返回一个值页面绑定的才能取得值，而methods中可以只执行逻辑代码，可以有返回值，也可以没有。</li>
<li>methods 一般定义事件触发函数,每次触发都会执行,即调我我就开干,不管有没有意义</li>
<li>computed 我只监听到影响我变化的关键信息 不用主动调我 我都会告诉你</li>
</ol>
<h1 id="%E6%8C%87%E4%BB%A4%E7%BB%86%E8%8A%82">指令细节</h1>
<h3 id="1-v-text-%E4%B8%8E-v-html">1. v-text 与 v-html</h3>
<blockquote>
<p>v-text 和直接{{text}}一样 类似 innerText</p>
</blockquote>
<blockquote>
<p>v-html 可内含标签 类似 innerHTML</p>
</blockquote>
<h3 id="2-v-if-%E4%B8%8E-v-show">2. v-if 与 v-show</h3>
<blockquote>
<p>v-if 节点存在与否</p>
</blockquote>
<blockquote>
<p>v-show 节点是否显示 display:none</p>
</blockquote>
<h3 id="3-v-cloak">3. v-cloak</h3>
<blockquote>
<p>防止显示 最原始的 vue 模板 如 <span>{{msg}}</span>会加载时闪一下</p>
</blockquote>
<h1 id="%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F">生命周期</h1>
<ol>
<li>beforeCreated el 和 data 并未初始化</li>
<li>created 完成 data 的初始化, el 并没有</li>
<li>beforeMounted 完成 el 和 data 的初始化,但未挂</li>
<li>mounted 完成挂载(dom 节点存在^-^)</li>
<li>beforeUpdate</li>
<li>update</li>
<li>actived</li>
<li>deactived</li>
<li>beforeaDestory</li>
<li>Destory</li>
</ol>
<blockquote>
<p>都有 before</p>
</blockquote>
<h1 id="%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C">组件注册</h1>
<h2 id="%E4%B8%80-%E5%85%A8%E5%B1%80%E6%B3%A8%E5%86%8C">一. 全局注册</h2>
<pre class="hljs"><code><div>Vue.component(<span class="hljs-string">"m-layout"</span>, {
  <span class="hljs-comment">// ... 选项 ...</span>
});
</div></code></pre>
<blockquote>
<p>直接使用 无需挂载</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">m-layout</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-layout</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">components</span>: {}
});
</div></code></pre>
<h2 id="%E4%BA%8C-%E5%B1%80%E9%83%A8%E6%B3%A8%E5%86%8C">二. 局部注册</h2>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> Layout = <span class="hljs-keyword">new</span> extend({
  <span class="hljs-comment">// ... 选项 ...</span>
});
</div></code></pre>
<blockquote>
<p>不能直接使用，必须声明挂载</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">m-layout</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-layout</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">components</span>: {
    <span class="hljs-string">"m-layout"</span>: Layout <span class="hljs-comment">//使用必须声明引入</span>
  }
});
</div></code></pre>
<blockquote>
<p>下面可行否?</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">m-layout</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-layout</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
   
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
</div></code></pre>
<h1 id="%E7%BB%84%E4%BB%B6%E9%80%9A%E4%BF%A1">组件通信</h1>
<h2 id="%E4%B8%80-props-%E5%90%91%E4%B8%8B">一. props 向下</h2>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">m-child</span> <span class="hljs-attr">:message</span>=<span class="hljs-string">"pageMsg"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-child</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">//子组件</span>
Vue.component(<span class="hljs-string">"m-child"</span>, {
  <span class="hljs-comment">// 在 JavaScript 中使用 camelCase</span>
  props: [<span class="hljs-string">"message"</span>],
  <span class="hljs-attr">template</span>:
    <span class="hljs-string">' &lt;input type="text" class="form-control" placeholder="" v-model="message"&gt;'</span>
});
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">pageMsg</span>: <span class="hljs-string">"aaa"</span>
  }
});
</div></code></pre>
<p>注:</p>
<blockquote>
<p>1.非引用内容对象传入，子组件变化不影响父组件<br>
2.如需相互同步 .sync<br>
3.如多层嵌套是否很麻烦？</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">m-child</span> <span class="hljs-attr">:message.sync</span>=<span class="hljs-string">"pageMsg"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-child</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h2 id="%E4%BA%8C-emmit-%E5%90%91%E4%B8%8A%E4%BC%A0%E9%80%92">二. emmit 向上传递</h2>
<pre class="hljs"><code><div><span class="hljs-comment">//子组件</span>
Vue.component(<span class="hljs-string">"m-child"</span>, {
  <span class="hljs-attr">template</span>: <span class="hljs-string">'&lt;button v-on:click="increment"&gt;{{ counter }}&lt;/button&gt;'</span>,
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">counter</span>: <span class="hljs-number">0</span>
    };
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">increment</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">this</span>.counter += <span class="hljs-number">1</span>;
      <span class="hljs-comment">//触发自定义increment1的函数。此处的increment1函数就是 incrementTotal1函数。</span>
      <span class="hljs-keyword">this</span>.$emit(<span class="hljs-string">"m-child-increment"</span>, <span class="hljs-string">"这个位子是可以加参数的"</span>);
    }
  }
});

<span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">total</span>: <span class="hljs-number">0</span>
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">abc</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
      <span class="hljs-keyword">this</span>.total += <span class="hljs-number">1</span>;
    }
  }
});
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">m-child</span> <span class="hljs-attr">v-on:m-child-increment</span>=<span class="hljs-string">"abc"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-child</span>&gt;</span>
  {{total}}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<blockquote>
<p>可理解为事件冒泡</p>
</blockquote>
<h2 id="%E4%B8%89-%E5%AD%90%E7%BB%84%E4%BB%B6%E8%B0%83%E7%88%B6-parent%E6%88%96root-%E4%B8%80%E8%88%AC%E4%B8%8D%E8%A6%81%E7%94%A8-%E5%BC%BA%E8%80%A6%E5%90%88">三. 子组件调父 $parent或$root 一般不要用 强耦合</h2>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>{{counter}} <span class="hljs-tag">&lt;<span class="hljs-name">runoob</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">runoob</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// 注册</span>
Vue.component(<span class="hljs-string">"runoob"</span>, {
  <span class="hljs-attr">template</span>: <span class="hljs-string">"&lt;h1 @click='add'&gt;自定义组件!&lt;/h1&gt;"</span>,
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">add</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">this</span>.$parent.counter++;
    }
  }
});

<span class="hljs-comment">// 创建根实例</span>
<span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">counter</span>: <span class="hljs-number">1</span>
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">add</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      counter++;
    }
  }
});
</div></code></pre>
<h2 id="%E5%9B%9B-ref-%E4%B8%80%E8%88%AC%E4%B8%8D%E8%A6%81%E7%94%A8-%E5%BC%BA%E8%80%A6%E5%90%88-%E6%9C%80%E5%A4%96%E5%B1%82%E5%8F%AF%E7%94%A8">四. ref 一般不要用 强耦合 最外层可用</h2>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">runoob</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"runoob_01"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">runoob</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"abc"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"点击我,我能过ref找到子组件的"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// 注册</span>
Vue.component(<span class="hljs-string">"runoob"</span>, {
  <span class="hljs-attr">template</span>: <span class="hljs-string">"&lt;h1 @click='add'&gt;{{title}}&lt;/h1&gt;"</span>,
  data() {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">title</span>: <span class="hljs-string">"自定义组件!"</span>
    };
  }
});

<span class="hljs-comment">// 创建根实例</span>
<span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {},
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">abc</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.$refs.runoob_01);
      <span class="hljs-keyword">this</span>.$refs.runoob_01.title = <span class="hljs-string">"我通过ref改了你"</span>;
    }
  }
});
</div></code></pre>
<h2 id="%E4%B8%89-%E5%8D%95%E9%9D%A2%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE%E5%AE%9E%E4%BD%93-vuex-%E5%90%8E%E9%9D%A2%E5%8D%95%E7%8B%AC%E8%AE%B2">三. 单面共享数据实体 vuex 后面单独讲</h2>
<blockquote>
<p>统一的实体对象,全局共用</p>
</blockquote>
<h1 id="%E6%8F%92%E6%A7%BD%E5%86%85%E5%AE%B9%E5%88%86%E5%8F%91">插槽=&gt;内容分发</h1>
<h2 id="%E4%B8%80-%E9%BB%98%E8%AE%A4%E5%9D%91%E4%BD%8D">一. 默认坑位</h2>
<h3 id="1-%E6%B3%A8%E5%86%8C%E4%B8%8A%E9%9D%A2%E7%BB%84%E4%BB%B6%E4%B8%BA-m-layout">1. 注册上面组件为 m-layout</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">slot</span>&gt;</span>前方高能,注意脚下<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h3 id="2-%E5%9C%BA%E6%99%AF%E4%B8%80">2. 场景一</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">m-layout</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-layout</span>&gt;</span>
</div></code></pre>
<p>输出</p>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>前方高能,注意脚下<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h3 id="3-%E5%9C%BA%E6%99%AF%E4%BA%8C">3. 场景二</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">m-layout</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>我要进坑<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">m-layout</span>&gt;</span>
</div></code></pre>
<p>输出</p>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>我要进坑<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h2 id="%E4%BA%8C-%E5%A4%9A%E6%8F%92%E6%A7%BD-%E5%A4%9A%E4%B8%AA%E5%9D%91">二. 多插槽 多个坑</h2>
<h3 id="1-%E7%BB%84%E4%BB%B6%E6%A8%A1%E6%9D%BF%E6%88%91%E6%9D%A5%E6%8C%96%E4%B8%89%E4%B8%AA%E5%9D%91-%E8%BF%98%E7%BB%99%E5%8F%96%E4%B8%AA%E5%90%8D%E5%AD%97">1. 组件模板=&gt;我来挖三个坑 还给取个名字</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span>科达视频会议管理系统<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span>主体内容<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span>技术支持:雪夜惊鸿<span class="hljs-tag">&lt;/<span class="hljs-name">slot</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h3 id="2-%E8%BE%93%E5%85%A5%E6%88%91%E6%9D%A5%E5%A1%AB-%E6%9C%AA%E7%9F%A5%E5%9D%91%E5%90%8D-%E6%8E%89%E5%93%AA%E7%AE%97%E5%93%AA">2. 输入=&gt;我来填 未知坑名 掉哪算哪</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span>我来填坑<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h3 id="3-%E8%BE%93%E5%87%BA%E7%BB%93%E6%9E%9C%E6%8E%89%E5%88%B0%E6%B2%A1%E5%8F%96%E5%90%8D%E5%AD%97%E5%9D%91">3. 输出结果=&gt;掉到没取名字坑</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span>科达视频会议管理系统<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span>我来填坑<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span>技术支持:雪夜惊鸿<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h3 id="4-%E8%BE%93%E5%85%A5%E6%88%91%E6%9D%A5%E5%A1%AB-%E4%BD%86%E6%88%91%E6%9C%89%E7%BB%8F%E9%AA%8C-%E7%9F%A5%E9%81%93%E5%9D%91%E5%90%8D%E5%9D%91%E6%AF%94%E8%BE%83%E6%B5%85">4. 输入=&gt;我来填 但我有经验 知道**(坑名)坑比较浅</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span>科达用户管理系统<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>我来填坑<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h3 id="5-%E8%BE%93%E5%87%BA%E7%BB%93%E6%9E%9C-%E6%8C%87%E5%AE%9A%E4%BC%98%E5%85%88-%E4%B8%8D%E6%8C%87%E5%AE%9A%E7%9C%8B%E6%88%91%E6%9C%89%E9%BB%98%E8%AE%A4%E5%9D%91%E4%BD%8D%E6%B2%A1-%E6%9C%89%E5%B0%B1%E7%BB%99%E4%BD%A0">5. 输出结果 =&gt; 指定优先 不指定看我有默认坑位没 有就给你</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span>科达用户管理系统<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span>我来填坑<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span>技术支持:雪夜惊鸿<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h1 id="%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F">指令系统</h1>
<h2 id="%E6%8F%90%E4%BE%9B%E4%BB%A5%E4%B8%8B%E9%92%A9%E5%AD%90">提供以下钩子</h2>
<blockquote>
<h3 id="1-bind%EF%BC%9A%E5%8F%AA%E8%B0%83%E7%94%A8%E4%B8%80%E6%AC%A1%EF%BC%8C%E6%8C%87%E4%BB%A4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BB%91%E5%AE%9A%E5%88%B0%E5%85%83%E7%B4%A0%E6%97%B6%E8%B0%83%E7%94%A8%E3%80%82%E5%9C%A8%E8%BF%99%E9%87%8C%E5%8F%AF%E4%BB%A5%E8%BF%9B%E8%A1%8C%E4%B8%80%E6%AC%A1%E6%80%A7%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E8%AE%BE%E7%BD%AE%E3%80%82">1. bind：只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。</h3>
<h3 id="2-inserted%EF%BC%9A%E8%A2%AB%E7%BB%91%E5%AE%9A%E5%85%83%E7%B4%A0%E6%8F%92%E5%85%A5%E7%88%B6%E8%8A%82%E7%82%B9%E6%97%B6%E8%B0%83%E7%94%A8-%E4%BB%85%E4%BF%9D%E8%AF%81%E7%88%B6%E8%8A%82%E7%82%B9%E5%AD%98%E5%9C%A8%EF%BC%8C%E4%BD%86%E4%B8%8D%E4%B8%80%E5%AE%9A%E5%B7%B2%E8%A2%AB%E6%8F%92%E5%85%A5%E6%96%87%E6%A1%A3%E4%B8%AD%E3%80%82">2. inserted：被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中)。</h3>
<h3 id="3-update%EF%BC%9A%E6%89%80%E5%9C%A8%E7%BB%84%E4%BB%B6%E7%9A%84-vnode-%E6%9B%B4%E6%96%B0%E6%97%B6%E8%B0%83%E7%94%A8%EF%BC%8C%E4%BD%86%E6%98%AF%E5%8F%AF%E8%83%BD%E5%8F%91%E7%94%9F%E5%9C%A8%E5%85%B6%E5%AD%90-vnode-%E6%9B%B4%E6%96%B0%E4%B9%8B%E5%89%8D%E3%80%82%E6%8C%87%E4%BB%A4%E7%9A%84%E5%80%BC%E5%8F%AF%E8%83%BD%E5%8F%91%E7%94%9F%E4%BA%86%E6%94%B9%E5%8F%98%EF%BC%8C%E4%B9%9F%E5%8F%AF%E8%83%BD%E6%B2%A1%E6%9C%89%E3%80%82%E4%BD%86%E6%98%AF%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E6%AF%94%E8%BE%83%E6%9B%B4%E6%96%B0%E5%89%8D%E5%90%8E%E7%9A%84%E5%80%BC%E6%9D%A5%E5%BF%BD%E7%95%A5%E4%B8%8D%E5%BF%85%E8%A6%81%E7%9A%84%E6%A8%A1%E6%9D%BF%E6%9B%B4%E6%96%B0-%E8%AF%A6%E7%BB%86%E7%9A%84%E9%92%A9%E5%AD%90%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E8%A7%81%E4%B8%8B%E3%80%82">3. update：所在组件的 VNode 更新时调用，但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变，也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。</h3>
<h3 id="4-componentupdated%EF%BC%9A%E6%8C%87%E4%BB%A4%E6%89%80%E5%9C%A8%E7%BB%84%E4%BB%B6%E7%9A%84-vnode-%E5%8F%8A%E5%85%B6%E5%AD%90-vnode-%E5%85%A8%E9%83%A8%E6%9B%B4%E6%96%B0%E5%90%8E%E8%B0%83%E7%94%A8%E3%80%82">4. componentUpdated：指令所在组件的 VNode 及其子 VNode 全部更新后调用。</h3>
<h3 id="5-unbind%EF%BC%9A%E5%8F%AA%E8%B0%83%E7%94%A8%E4%B8%80%E6%AC%A1%EF%BC%8C%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%85%83%E7%B4%A0%E8%A7%A3%E7%BB%91%E6%97%B6%E8%B0%83%E7%94%A8%E3%80%82">5. unbind：只调用一次，指令与元素解绑时调用。</h3>
</blockquote>
<h2 id="%E7%A4%BA%E4%BE%8B%E4%B8%80-%E8%87%AA%E5%8A%A8-focus">示例一 自动 focus</h2>
<h3 id="1-%E6%B3%A8%E5%86%8C%E6%8C%87%E4%BB%A4-%E7%A4%BA%E4%BE%8B">1. 注册指令 示例</h3>
<pre class="hljs"><code><div><span class="hljs-comment">// 注册一个全局自定义指令 `v-focus`</span>
Vue.directive(<span class="hljs-string">"focus"</span>, {
  <span class="hljs-comment">// 当被绑定的元素插入到 DOM 中时……</span>
  inserted: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">el</span>) </span>{
    <span class="hljs-comment">// 聚焦元素</span>
    el.focus();
  }
});
</div></code></pre>
<h3 id="2-%E4%BD%BF%E7%94%A8%E6%8C%87%E4%BB%A4">2. 使用指令</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">v-focus</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<h1 id="%E9%94%AE%E7%9B%98%E7%9B%91%E5%90%AC">键盘监听</h1>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"请输入"</span> @<span class="hljs-attr">keyup.enter</span>=<span class="hljs-string">"show"</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span> /&gt;</span>
</div></code></pre>
<h1 id="%E6%B7%B7%E5%85%A5">混入</h1>
<blockquote>
<p>将两个的对象的混合为一个数组，彼此都可以被调用, 类似于继承</p>
</blockquote>
<h2 id="%E4%B8%80-%E5%9F%BA%E6%9C%AC%E7%A4%BA%E4%BE%8B">一. 基本示例</h2>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> my_mixin = {
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">needLogin</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">ticket</span>: sessionStorage.getItem(<span class="hljs-string">"ticket"</span>)
    };
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">loginOut</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      alert(<span class="hljs-string">"登出"</span>);
    },
    <span class="hljs-attr">login</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      alert(<span class="hljs-string">"登陆成功"</span>);
    }
  }
};

<span class="hljs-keyword">var</span> app = <span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">mixins</span>: [my_mixin],
  <span class="hljs-attr">mounted</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{}
});
</div></code></pre>
<h2 id="%E4%BA%8C-%E6%B7%B7%E5%85%A5%E6%89%A7%E8%A1%8C%E8%A7%84%E5%88%99">二. 混入执行规则</h2>
<h3 id="1-%E5%A6%82%E6%9E%9C%E6%B7%B7%E5%85%A5%E5%AF%B9%E8%B1%A1%E5%92%8C%E7%BB%84%E4%BB%B6%E5%B1%9E%E6%80%A7%EF%BC%8C%E6%96%B9%E6%B3%95%E7%AD%89%E6%9C%89%E5%86%B2%E7%AA%81%EF%BC%8C%E9%81%B5%E5%BE%AA%E4%BB%A5%E4%B8%8B%E8%A7%84%E5%88%99%EF%BC%9A">1. 如果混入对象和组件属性，方法等有冲突，遵循以下规则：</h3>
<blockquote>
<p>1、数据对象在内部会进行浅合并 (一层属性深度)，在和组件的数据发生冲突时以组件数据优先。<br>
2、同名钩子函数将混合为一个数组，因此都将被调用。另外，混入对象的钩子将在组件自身钩子之前调用</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> my_mixin = {
  <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"混入对象的钩子被调用"</span>);
  }
};

<span class="hljs-keyword">var</span> app = <span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">mixins</span>: [my_mixin],
  <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"组件钩子被调用"</span>);
  }
});
</div></code></pre>
<p>输出</p>
<blockquote>
<p>组件钩子被调用<br>
混入对象的钩子被调用</p>
</blockquote>
<blockquote>
<p>值为对象的选项，例如 methods, components 和 directives，将被混合为同一个对象。两个对象键名冲突时，取组件对象的键值对</p>
</blockquote>
<pre class="hljs"><code><div>Vue.mixin({
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>);
    }
  }
});

<span class="hljs-keyword">var</span> app = <span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hello"</span>);
    }
  }
});

app.sayHello();
</div></code></pre>
<h1 id="keepalive-%E7%BC%93%E5%AD%98%E8%A2%AB%E5%8C%85%E8%A3%B9%E7%BB%84%E4%BB%B6">KeepAlive 缓存被包裹组件</h1>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">keep-alive</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">router-view</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"$route.meta.keepAlive"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">keep-alive</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">router-view</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"!$route.meta.keepAlive"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
</div></code></pre>
<h2 id="%E7%A4%BA%E4%BE%8B%E4%B8%80">示例一</h2>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>我裸奔<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">m-test</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"show"</span> <span class="hljs-attr">:no</span>=<span class="hljs-string">"1"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-test</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>我有保护层<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">keep-alive</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">m-test</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"show"</span> <span class="hljs-attr">:no</span>=<span class="hljs-string">"2"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">m-test</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">keep-alive</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"toggleShow"</span>&gt;</span>切换<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div>Vue.component(<span class="hljs-string">"m-test"</span>, {
  <span class="hljs-attr">template</span>: <span class="hljs-string">"&lt;div&gt;{{times}}&lt;/div&gt;"</span>,
  <span class="hljs-attr">props</span>: [<span class="hljs-string">"no"</span>],
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">times</span>: <span class="hljs-number">0</span>
    };
  },
  <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">this</span>.times = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getTime();
  },
  <span class="hljs-attr">activated</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.no + <span class="hljs-string">":activated"</span>);
  }
});

<span class="hljs-comment">// 创建根实例</span>
<span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">show</span>: <span class="hljs-literal">true</span>
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">toggleShow</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">this</span>.show = !<span class="hljs-keyword">this</span>.show;
    }
  }
});
</div></code></pre>
<p>点按纽隐藏显示一下后 输出效果</p>
<blockquote>
<p>有 keep-alive 的显示不变<br>
2:activated</p>
</blockquote>
<h1 id="vuenexttick">Vue.nextTick</h1>
<blockquote>
<p>与 jquery 混用时你会遇到的坑</p>
</blockquote>
<p>导致原因</p>
<blockquote>
<p>Vue 实现响应式并不是数据发生变化之后 DOM 立即变化，而是按一定的策略进行 DOM 的更新,说白了就是异步的</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">list</span>: []
  },
  <span class="hljs-attr">mounted</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">this</span>.getData();
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">getData</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">this</span>.$http.get(<span class="hljs-string">"/api/article"</span>).then(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">res</span>) </span>{
        <span class="hljs-keyword">this</span>.list = res.data.data.list;
        <span class="hljs-comment">// ref  list 引用了ul元素，我想把第一个li颜色变为红色</span>
        <span class="hljs-keyword">this</span>.$refs.list.getElementsByTagName(<span class="hljs-string">"li"</span>)[<span class="hljs-number">0</span>].style.color = <span class="hljs-string">"red"</span>;
      });
    }
  }
});
</div></code></pre>
<blockquote>
<p>是否会出现问题? 如何解决</p>
</blockquote>
<h3 id="%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E4%B8%80">解决方案一</h3>
<pre class="hljs"><code><div>Vue.$nextTick(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">//代码放这里面</span>
});
</div></code></pre>
<h3 id="%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E4%BA%8C">解决方案二</h3>
<pre class="hljs"><code><div>setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">//代码放这里面</span>
},<span class="hljs-number">0</span>);
</div></code></pre>
<h1 id="%E5%8A%A8%E6%80%81%E7%BB%84%E4%BB%B6">动态组件</h1>
<h3 id="%E7%A4%BA%E4%BE%8B">示例</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"to('A')"</span>&gt;</span>A<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"to('B')"</span>&gt;</span>B<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"to('C')"</span>&gt;</span>C<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">component</span> <span class="hljs-attr">v-bind:is</span>=<span class="hljs-string">"currentTabComponent"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">component</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> A = Vue.extend({
  <span class="hljs-attr">template</span>: <span class="hljs-string">"&lt;div&gt;AAAAAAAAAAAAAAAA&lt;/div&gt;"</span>,
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {};
  }
});

<span class="hljs-keyword">var</span> B = Vue.extend({
  <span class="hljs-attr">template</span>: <span class="hljs-string">"&lt;div&gt;BBBBBBBBBBBBBBBBBBBBBBB&lt;/div&gt;"</span>,
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {};
  }
});

<span class="hljs-keyword">var</span> C = Vue.extend({
  <span class="hljs-attr">template</span>: <span class="hljs-string">"&lt;div&gt;CCCCCCCCCCCCCCCCCCCCCCC&lt;/div&gt;"</span>,
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {};
  }
});

<span class="hljs-comment">// 创建根实例</span>
<span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">currentTabComponent</span>: <span class="hljs-string">"A"</span>
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">to</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">to</span>) </span>{
      <span class="hljs-keyword">this</span>.currentTabComponent = to;
    }
  },
  <span class="hljs-attr">components</span>: {
    A,
    B,
    C
  }
});
</div></code></pre>
<h1 id="%E7%BB%84%E4%BB%B6%E9%80%92%E5%BD%92">组件递归</h1>
<blockquote>
<p>斐波那契数列 0 1 1 2 3 5 8</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">F</span>(<span class="hljs-params">n</span>) </span>{
  <span class="hljs-keyword">if</span> (n &lt;= <span class="hljs-number">1</span>) {
    <span class="hljs-keyword">return</span> n;
  }
  <span class="hljs-keyword">return</span> F(n - <span class="hljs-number">1</span>) + F(n - <span class="hljs-number">2</span>);
}
</div></code></pre>
<blockquote>
<p>自已嵌自己+出口</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">AAAA</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">AAAA</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"出品"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">AAA</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">AAA</span>&gt;</span>
</div></code></pre>
<h2 id="%E7%9C%8B%E7%9C%8B%E5%B8%B8%E5%B7%A6%E4%BE%A7%E8%8F%9C%E5%8D%95%E6%A0%BC%E5%BC%8F-%E9%80%92%E5%BD%92">看看常左侧菜单格式 递归</h2>
<pre class="hljs"><code><div>[{
    id:<span class="hljs-number">100</span>
    title:'一级菜单',
    children:[{
        id:<span class="hljs-number">10001</span>
        title:'二级菜单',
        children:[]
    }]
},
{
    id:<span class="hljs-number">101</span>
    title:'一级菜单',
    children:[]
}]
</div></code></pre>
<p>常用模板</p>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>一级菜单<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>二级菜单<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>二级菜单<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>一级菜单<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>二级菜单<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      =
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> Tree = Vue.extend({
  <span class="hljs-attr">template</span>: <span class="hljs-string">`
    &lt;li&gt;
      &lt;a&gt;{{tree.title}}&lt;/a&gt;
      &lt;ul&gt;
        &lt;Tree v-if="tree.children" :tree="item"  v-for="item in tree.children"&gt;{{item.title}}&lt;/Tree&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
  `</span>,
  <span class="hljs-attr">props</span>: [<span class="hljs-string">"tree"</span>],
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {};
  },
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Tree"</span>
});
</div></code></pre>
<blockquote>
<p>当组件拥有 name 属性的时候，就可以在它的模板内递归的调用自己</p>
<p>递归一般都需要了出口</p>
<p>为了防止出现死循环，在调用自身的时候，加入了 v-if 作为判定条件</p>
</blockquote>
<h3 id="vue%E6%9C%80%E5%BC%80%E5%A7%8B%E6%98%AF%E5%BA%94%E7%94%A8%E4%BA%8Ewebapp%E7%9A%84spasingle-page-application%E5%8D%B3%E5%8D%95%E9%A1%B5%E5%BA%94%E7%94%A8">vue最开始是应用于webApp的SPA(Single Page Application),即单页应用</h3>
<ol>
<li>
<p>页面跳白屏 过渡效果支持不好  <a href="https://vux.li/demos/v2/#/demo">vux</a></p>
</li>
<li>
<p>只有一个html入口, 每个所谓的页面就是一个组件</p>
</li>
</ol>
<h1 id="%E6%B7%B1%E5%85%A5%E4%B8%80%E4%B8%8B-vue%E8%87%AA%E5%B8%A6componets%E7%BB%84%E4%BB%B6">深入一下  vue自带componets组件</h1>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">componets</span> <span class="hljs-attr">:is</span>=<span class="hljs-string">"A"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">componets</span>&gt;</span>
</div></code></pre>
<p>http://localhost:90/WebDemo//05_Vue/03/com_toggle.html</p>
<p>http://localhost:90/WebDemo//05_Vue/03/com_toggle.html#curComponents=A&amp;id=1</p>
<blockquote>
<p>is作为参数传入? 那是否可以从URL传入呢
www.abc.com?isComponents=A&amp;id=1</p>
</blockquote>
<pre class="hljs"><code><div>  <span class="hljs-tag">&lt;<span class="hljs-name">component</span> <span class="hljs-attr">v-bind:is</span>=<span class="hljs-string">"currentTabComponent"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">component</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> A = Vue.extend({
  <span class="hljs-attr">template</span>: <span class="hljs-string">"&lt;div&gt;编号:{{id}}&lt;/div&gt;"</span>,
  <span class="hljs-attr">props</span>:[<span class="hljs-string">"id"</span>],
  <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> {};
  }
});
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">el</span>: <span class="hljs-string">"#app"</span>,
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">currentTabComponent</span>: getValueByKeyFromUrl(<span class="hljs-string">'isComponents'</span>)
  },
  <span class="hljs-attr">methods</span>: {
    <span class="hljs-attr">to</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">to</span>) </span>{
      <span class="hljs-keyword">this</span>.currentTabComponent = to;
    }
  },
  <span class="hljs-attr">components</span>: {
    A,
    B,
    C
  }
});
</div></code></pre>
<h3 id="%E8%A6%81%E6%B1%82">要求</h3>
<ol>
<li>通过url传入相前显示的组件,但页面不能刷新</li>
<li>在页面内切换组件,需要反馈到url上面</li>
</ol>
<h3 id="url%E5%8F%82%E6%95%B0%E5%B8%A6%E5%85%A5%E9%97%AE%E9%A2%98">url参数带入问题</h3>
<blockquote>
<p>url参数变化,会导致页面刷新
每次都重新加载不显示的组件</p>
</blockquote>
<h3 id="%E8%A7%A3%E5%86%B3">解决</h3>
<ol>
<li>hash  原生自带</li>
</ol>
<h3 id="%E6%BC%94%E7%A4%BA%E4%B8%80%E4%B8%8B">演示一下</h3>
<h3 id="%E6%BC%94%E7%A4%BA%E7%9B%AE%E6%A0%87">演示目标</h3>
<ol>
<li>#four 页面呈现状态  滚动到了#four的div</li>
<li>改hash值,页面不会刷新</li>
<li>能监测到hash变化,并能取得到</li>
</ol>
<h3 id="%E6%8A%9B%E9%97%AE%E9%A2%98">抛问题</h3>
<ol>
<li>每个页面是一个组件,那如何传参, 比如: 修改页我要传 id进去</li>
<li>页面返回时,上一个组件是重新created吗,如何状态保持</li>
<li>切换组件时,让组件刷新或不刷新</li>
<li>既然是单页,那是不是所有的组件第一次都需 [全部] [所有] 加载,那js好大呀. 有没有按需?</li>
</ol>
<h1 id="vue-cli%E8%84%9A%E6%89%8B%E6%9E%B6">vue-cli脚手架</h1>
<pre class="hljs"><code><div>npm install vue -g
npm install webpack webpack-cli -g
npm install --global vue-cli
vue init webpack myapp
npm install 
</div></code></pre>
<h1 id="vue-router-%E5%8D%95%E9%A1%B5%E8%B7%AF%E5%BE%84">vue-router 单页路径</h1>
<h2 id="%E5%9F%BA%E6%9C%AC%E7%A4%BA%E4%BE%8B">基本示例</h2>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mt_20"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">router-link</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-success"</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/one"</span>&gt;</span>用户列表<span class="hljs-tag">&lt;/<span class="hljs-name">router-link</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">router-link</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-success"</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/two"</span>&gt;</span>部门列表<span class="hljs-tag">&lt;/<span class="hljs-name">router-link</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">router-link</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-success"</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/three/1001"</span>&gt;</span>新增<span class="hljs-tag">&lt;/<span class="hljs-name">router-link</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">router-view</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mt_20"</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div>Vue.use(VueRouter);
<span class="hljs-keyword">var</span> router = <span class="hljs-keyword">new</span> VueRouter({
  <span class="hljs-attr">routes</span>: [
    {
      <span class="hljs-attr">path</span>: <span class="hljs-string">"/one"</span>,
      <span class="hljs-attr">component</span>: One
    },
    {
      <span class="hljs-attr">path</span>: <span class="hljs-string">"/two"</span>,
      <span class="hljs-attr">component</span>: TWo
    },
    {
      <span class="hljs-attr">path</span>: <span class="hljs-string">"/three/:userId"</span>,
      <span class="hljs-attr">component</span>: Three
    }
  ]
});

<span class="hljs-keyword">var</span> app = <span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">router</span>: router
}).$mount(<span class="hljs-string">"#app"</span>);
</div></code></pre>
<h2 id="%E7%9B%91%E5%90%AC">监听</h2>
<blockquote>
<p>www.88.com/pages/#One<br>
www.88.com/pages/#Two<br>
www.88.com/pages/#Three/1</p>
</blockquote>
<h2 id="%E4%B8%A4%E7%A7%8D%E8%B7%AF%E7%94%B1%E5%88%87%E6%8D%A2%E6%A8%A1%E5%BC%8F">两种路由切换模式</h2>
<h2 id="hash-%E6%A8%A1%E5%BC%8F">hash 模式</h2>
<blockquote>
<p>hash 模式背后的原理是 onhashchange 事件</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-built_in">window</span>.onhashchange = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">event</span>) </span>{
  <span class="hljs-built_in">console</span>.log(event.oldURL, event.newURL);
  <span class="hljs-keyword">let</span> hash = location.hash.slice(<span class="hljs-number">1</span>);
  <span class="hljs-built_in">document</span>.body.style.color = hash;
};
</div></code></pre>
<h3 id="%E9%83%BD%E5%B8%A6hash%E5%8F%B7url%E4%B8%8D%E7%BE%8E%E8%A7%82%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88">都带hash#号url不美观解决方案</h3>
<blockquote>
<p>www.88.com/meeting/index.html/#One 这种路由带# nginx rewrite 解决</p>
</blockquote>
<h3 id="history-%E6%A8%A1%E5%BC%8F-%E6%9A%82%E4%B8%8D%E4%BA%86%E8%A7%A3">history 模式 暂不了解</h3>
<h2 id="router-%E5%B5%8C%E5%A5%97">router 嵌套</h2>
<h3 id="%E7%A4%BA%E4%BE%8B%E4%B8%80-%E5%B5%8C%E5%A5%97%E6%A8%A1%E6%9D%BF%E5%90%88%E5%B9%B6">示例一 嵌套模板合并</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-header"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-body"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>我要进坑<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout-footer"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-layout"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"home"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</div></code></pre>
<blockquote>
<p>return 上面的组件  导致所有页面组件都要嵌上这个</p>
</blockquote>
<pre class="hljs"><code><div>{
    <span class="hljs-attr">path</span>: <span class="hljs-string">'/needLayout'</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">''</span>,
    <span class="hljs-attr">component</span>:Layout,
    <span class="hljs-attr">children</span>:[{
        <span class="hljs-attr">path</span>: <span class="hljs-string">'/home'</span>,
        <span class="hljs-attr">name</span>: <span class="hljs-string">'home'</span>,
        <span class="hljs-attr">component</span>:Home
    },{
        <span class="hljs-attr">path</span>: <span class="hljs-string">'/aaa'</span>,
        <span class="hljs-attr">name</span>: <span class="hljs-string">'aaa'</span>,
        <span class="hljs-attr">component</span>:AAA
    }]
}
</div></code></pre>
<blockquote>
<p>/#needLayout/home</p>
</blockquote>
<p>问题: 有头部和底部的居多</p>
<h3 id="%E7%A4%BA%E4%BE%8B%E4%BA%8C-%E5%8F%8D%E5%90%91%E5%86%99%E8%B7%AF%E7%94%B1">示例二 反向写路由</h3>
<pre class="hljs"><code><div>[
  {
    <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">''</span>,
    <span class="hljs-attr">component</span>:Layout,
    <span class="hljs-attr">children</span>:[{
        <span class="hljs-attr">path</span>: <span class="hljs-string">'/home'</span>,
        <span class="hljs-attr">name</span>: <span class="hljs-string">'home'</span>,
        <span class="hljs-attr">component</span>:Home
    }]
  },
  {
     <span class="hljs-attr">path</span>: <span class="hljs-string">'/login'</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">'login'</span>,
    <span class="hljs-attr">component</span>:Login,
  }
]
</div></code></pre>
<blockquote>
<p>Layout 组件的<router-view></router-view>填充 Home 组件</p>
</blockquote>
<h2 id="%E8%B7%AF%E7%94%B1%E4%BC%A0%E5%8F%82">路由传参</h2>
<h2 id="%E7%A4%BA%E4%BE%8B%E4%B8%80-thisrouteparamsid">示例一    this.$route.params.id</h2>
<pre class="hljs"><code><div>{
  <span class="hljs-attr">path</span>: <span class="hljs-string">'/HelloWorld/:id'</span>,
  <span class="hljs-attr">name</span>: <span class="hljs-string">'HelloWorld'</span>,
  <span class="hljs-attr">component</span>: HelloWorld
}
</div></code></pre>
<pre class="hljs"><code><div>data () {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">msg</span>: <span class="hljs-string">'HelloWorld'</span>,
    <span class="hljs-attr">id</span>:<span class="hljs-keyword">this</span>.$route.params.id
  }
}
</div></code></pre>
<blockquote>
<p>输入 HelloWorld/2<br>
输出 2</p>
</blockquote>
<p>示例二  route.query直接注入 props</p>
<pre class="hljs"><code><div>{
  <span class="hljs-attr">path</span>: <span class="hljs-string">'/HelloWorld/:id'</span>,
  <span class="hljs-attr">name</span>: <span class="hljs-string">'HelloWorld'</span>,
  <span class="hljs-attr">component</span>: HelloWorld,
  <span class="hljs-attr">props</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">route</span>) </span>{
    <span class="hljs-keyword">return</span> { <span class="hljs-attr">query</span>: route.query.q }
  }
}
</div></code></pre>
<pre class="hljs"><code><div>data () {
  <span class="hljs-attr">props</span>: [<span class="hljs-string">"query"</span>],
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">msg</span>: <span class="hljs-string">'HelloWorld'</span>,
    <span class="hljs-attr">id</span>:<span class="hljs-keyword">this</span>.$route.params.id
  }
}
</div></code></pre>
<h1 id="%E7%BB%84%E4%BB%B6%E5%88%87%E6%8D%A2%E6%98%AF%E5%90%A6%E9%9C%80%E8%A6%81%E5%88%B7%E6%96%B0">组件切换是否需要刷新</h1>
<h3 id="html">html</h3>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">keep-alive</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- 会被缓存的视图组件 --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">router-view</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"显示这个"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"router-view"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">keep-alive</span>&gt;</span>

<span class="hljs-comment">&lt;!-- 不会被缓存的视图组件 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">router-view</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"显示这个"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"router-view"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
</div></code></pre>
<blockquote>
<p>单页入口 <router-view>有两个, 其中一个被keepAlive包,另一个不</p>
<p>根据某个条件让只显示其中一个</p>
</blockquote>
<h3 id="2-vue-router-meta-%E6%89%A9%E5%B1%95-%E9%85%8D%E7%BD%AE">2. vue-router meta 扩展 配置</h3>
<pre class="hljs"><code><div>[{
    <span class="hljs-attr">path</span>: <span class="hljs-string">'/Booking'</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">'Booking'</span>,
    <span class="hljs-attr">component</span>: three,
    <span class="hljs-attr">meta</span>: {
        <span class="hljs-attr">keepAlive</span>: <span class="hljs-literal">true</span>  <span class="hljs-comment">//默认要缓存</span>
    }
},{
    <span class="hljs-attr">path</span>: <span class="hljs-string">'/BookingDateSelect'</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">'BookingDateSelect'</span>,
    <span class="hljs-attr">component</span>: three,
    <span class="hljs-attr">meta</span>: {
        <span class="hljs-attr">keepAlive</span>: <span class="hljs-literal">false</span>  <span class="hljs-comment">//默认要缓存</span>
    }
}]
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-tag">&lt;<span class="hljs-name">keep-alive</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- 会被缓存的视图组件 --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">router-view</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"$route.meta.keepAlive"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"router-view"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">keep-alive</span>&gt;</span>
<span class="hljs-comment">&lt;!-- 不会被缓存的视图组件 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">router-view</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"!$route.meta.keepAlive"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"router-view"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">router-view</span>&gt;</span>
</div></code></pre>
<h1 id="vue-router-%E8%B7%AF%E7%94%B1%E9%92%A9%E5%AD%90%E5%AE%9E%E7%8E%B0%E5%89%8D%E8%BF%9B%E5%88%B7%E6%96%B0%E5%90%8E%E9%80%80%E4%B8%8D%E5%88%B7%E6%96%B0">vue-router 路由钩子实现前进刷新后退不刷新</h1>
<h3 id="%E5%BA%94%E7%94%A8%E7%94%A8%E5%9C%BA%E6%99%AF%E5%A6%82">应用用场景如:</h3>
<ol>
<li>
<p>选择页面</p>
<p>a.在机票购买页=&gt;出发日期选择页 内含价格日历(价格+库存) 每次都要刷新</p>
<p>b.选好后回机票购买页(不能刷新)</p>
</li>
</ol>
<h3 id="3-routerbeforeeach-%E8%B7%AF%E7%94%B1%E5%88%87%E6%8D%A2%E5%89%8D">3. router.beforeEach 路由切换前</h3>
<pre class="hljs"><code><div><span class="hljs-keyword">let</span> routerList = []
router.beforeEach(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span>, next</span>) =&gt;</span> {
    <span class="hljs-comment">//是否是最后一个</span>
    <span class="hljs-keyword">if</span> (routerList.length &amp;&amp; routerList.indexOf(to.name) === routerList.length - <span class="hljs-number">1</span>) {
        <span class="hljs-comment">// 后退</span>
        routerList.splice(routerList.length - <span class="hljs-number">1</span>, <span class="hljs-number">1</span>)
        to.meta.keepAlive = <span class="hljs-literal">true</span>
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// 前进</span>
        routerList.push(<span class="hljs-keyword">from</span>.name || <span class="hljs-string">'/'</span>)
        to.meta.keepAlive = <span class="hljs-literal">false</span>
    }
    next()
]);
</div></code></pre>
<h1 id="vue-router-%E6%9D%83%E9%99%90%E8%AE%BE%E8%AE%A1%E5%8A%A0%E8%BD%BD%E6%B5%AE%E5%B1%82%E7%AD%89%E5%8F%8A-meta-%E6%89%A9%E5%B1%95">vue-router 权限设计/加载浮层等及 Meta 扩展</h1>
<pre class="hljs"><code><div>{
    <span class="hljs-attr">path</span>: <span class="hljs-string">'admin/home'</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">'home'</span>,
    <span class="hljs-attr">component</span>:home
    meta: {
        <span class="hljs-attr">title</span>: <span class="hljs-string">'今日考勤(管理员)'</span>,
        <span class="hljs-attr">showBack</span>: <span class="hljs-literal">true</span>,
        <span class="hljs-attr">requireAuth</span>: <span class="hljs-literal">true</span> <span class="hljs-comment">// 添加该字段，表示进入这个路由是需要登录的</span>
    }
}
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-comment">// 页面刷新时，重新赋值token</span>
<span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.localStorage.getItem(<span class="hljs-string">"token"</span>)) {
  store.commit(<span class="hljs-string">"login"</span>, <span class="hljs-built_in">window</span>.localStorage.getItem(<span class="hljs-string">"token"</span>));
}

<span class="hljs-comment">//上面场景在问题没?</span>

router.beforeEach(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span>, next</span>) =&gt;</span> {
  <span class="hljs-comment">//显示正在加载</span>
  store.commit(<span class="hljs-string">"updateLoading"</span>, <span class="hljs-literal">true</span>);

  <span class="hljs-comment">//是否显示导航返回按纽</span>
  store.commit(<span class="hljs-string">"updateShowBack"</span>, to.meta.showBack == <span class="hljs-literal">false</span> ? <span class="hljs-literal">false</span> : <span class="hljs-literal">true</span>);

  <span class="hljs-comment">//如meta配置了标题,则更新标题</span>
  <span class="hljs-keyword">if</span> (to.meta &amp;&amp; to.meta.title &amp;&amp; to.meta.title.length &gt; <span class="hljs-number">0</span>) {
    store.commit(<span class="hljs-string">"updateTitle"</span>, to.meta.title);
  }

  <span class="hljs-comment">//如果检测到需要登陆 则看token是否存在 如不则到跳登陆页</span>
  <span class="hljs-keyword">if</span> (to.matched.some(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> r.meta.requireAuth)) {
    <span class="hljs-keyword">if</span> (store.state.token.length &gt; <span class="hljs-number">0</span>) {
      next();
    } <span class="hljs-keyword">else</span> {
      next({
        <span class="hljs-attr">path</span>: <span class="hljs-string">"/login"</span>,
        <span class="hljs-attr">query</span>: { <span class="hljs-attr">redirect</span>: to.fullPath }
      });
    }
  } <span class="hljs-keyword">else</span> {
    next();
  }
});

<span class="hljs-comment">//路由切换守成后隐藏加载框</span>
router.afterEach(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">to</span>) </span>{
  store.commit(<span class="hljs-string">"updateLoading"</span>, <span class="hljs-literal">false</span>);
});
</div></code></pre>
<h1 id="%E5%8D%95%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F">单文件格式</h1>
<h1 id="%E6%8F%92%E4%BB%B6">插件</h1>
<pre class="hljs"><code><div><span class="hljs-comment">// 用 Browserify 或 webpack 提供的 CommonJS 模块环境时</span>
<span class="hljs-keyword">var</span> Vue = <span class="hljs-built_in">require</span>(<span class="hljs-string">'vue'</span>)
<span class="hljs-keyword">var</span> VueRouter = <span class="hljs-built_in">require</span>(<span class="hljs-string">'vue-router'</span>)

<span class="hljs-comment">// 不要忘了调用此方法</span>
Vue.use(VueRouter)
</div></code></pre>
<pre class="hljs"><code><div>MyPlugin.install = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Vue, options</span>) </span>{
  <span class="hljs-comment">// 1. 添加全局方法或属性</span>
  Vue.myGlobalMethod = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// 逻辑...</span>
  }

  <span class="hljs-comment">// 2. 添加全局资源</span>
  Vue.directive(<span class="hljs-string">'my-directive'</span>, {
    bind (el, binding, vnode, oldVnode) {
      <span class="hljs-comment">// 逻辑...</span>
    }
    ...
  })

  <span class="hljs-comment">// 3. 注入组件</span>
  Vue.mixin({
    <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      <span class="hljs-comment">// 逻辑...</span>
    }
    ...
  })

  <span class="hljs-comment">// 4. 添加实例方法</span>
  Vue.prototype.$myMethod = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">methodOptions</span>) </span>{
    <span class="hljs-comment">// 逻辑...</span>
  }
}
</div></code></pre>
<h3 id="toastr%E6%8F%92%E4%BB%B6-%E5%8F%82%E8%80%83%E6%95%99%E7%A8%8B">toastr插件 <a href="https://segmentfault.com/a/1190000012224638#articleHeader1">参考教程</a></h3>
<h1 id="%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86">状态管理</h1>
<h3 id="1%E7%BB%84%E4%BB%B6%E5%A4%9A%E5%B1%82%E5%B5%8C%E5%A5%97%E4%BC%A0%E5%80%BC%E9%BA%BB%E7%83%A6">1.组件多层嵌套传值麻烦</h3>
<h3 id="2%E6%97%A2%E7%84%B6%E6%98%AF%E5%8D%95%E9%A1%B5%E9%A1%B5%E9%9D%A2%E6%98%AF%E4%B8%8D%E5%88%B7%E6%96%B0%E7%9A%84%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E5%85%A8%E5%B1%80%E5%85%B1%E4%B8%80%E4%B8%AA%E6%95%B0%E6%8D%AE%E6%BA%90-vuex">2.既然是单页,页面是不刷新的,是否可以全局共一个数据源  vuex</h3>
<h2 id="%E4%BB%80%E4%B9%88%E6%98%AFvuex">什么是vuex</h2>
<blockquote>
<ol>
<li>
<p>vuex就是在vue中创建全局变量的东西</p>
</li>
<li>
<p>vuex提供了一些优雅的方法，可以让我们改变全局变量的值</p>
</li>
</ol>
</blockquote>
<h2 id="%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5">核心概念</h2>
<blockquote>
<p>1、this.$store ： 我们可以通过 this.$store 在vue的组件中获取
vuex的实例。<br>
2、State ： vuex中的数据源，我们可以通过 this.$store.state 获取
我们在vuex中声明的全局变量的值。<br>
3、Getter： 相当于vue中的computed ， 及 计算属性， 可以用于监听、
计算 state中的值的变化<br>
4、Mutation： vuex中去操作数据的方法 （只能同步执行）<br>
5、Action： 用来操作 Mutation 的动作 ， 他不能直接去操作数据源，
但可以把mutation变为异步的</p>
</blockquote>
<h2 id="6%E3%80%81module%EF%BC%9A-%E6%A8%A1%E5%9D%97%E5%8C%96%EF%BC%8C%E5%BD%93%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E8%B6%B3%E5%A4%9F%E5%A4%A7%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E6%8A%8A%E4%BD%A0%E7%9A%84vuex%E5%88%86%E6%88%90%E5%A4%9A%E4%B8%AA%E5%AD%90%E6%A8%A1%E5%9D%97">6、Module： 模块化，当你的应用足够大的时候，你可以把你的vuex分成多个
子模块</h2>
<p>作者：LGD_Sunday
来源：CSDN
原文：https://blog.csdn.net/u011068996/article/details/80216154
版权声明：本文为博主原创文章，转载请附上博文链接！</p>
<pre class="hljs"><code><div><span class="hljs-comment">//store对象</span>
<span class="hljs-keyword">var</span> store = <span class="hljs-keyword">new</span> Vuex.Store({
    <span class="hljs-attr">state</span>: {
        <span class="hljs-attr">count</span>: <span class="hljs-number">1</span>
    },
    <span class="hljs-attr">mutations</span>: {
        increment(state) {
            state.count++
        }
    }
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> store;
</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">name</span>: <span class="hljs-string">"two"</span>,
  <span class="hljs-attr">methods</span>: {
    add() {
      <span class="hljs-comment">//this.$store.state.count+=1;</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.$store.commit(<span class="hljs-string">'increment'</span>)
    }
  },
  <span class="hljs-attr">computed</span>: {
    count() {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.$store.state.count;
    }
  }
};
</div></code></pre>
<blockquote>
<p>直接 this.$store.state.count+=1; 也是能改值的</p>
<p>但是似乎不太好统一控制</p>
<p>Mutation  更改 Vuex 的 store 中的状态的唯一方法 commit</p>
</blockquote>
<pre class="hljs"><code><div> <span class="hljs-keyword">this</span>.$store.commit(<span class="hljs-string">'increment'</span>)
</div></code></pre>
<blockquote>
<p>可传参</p>
</blockquote>
<pre class="hljs"><code><div> <span class="hljs-keyword">this</span>.$store.commit(<span class="hljs-string">'increment'</span>,num)
</div></code></pre>
<h3 id="%E9%97%AE%E9%A2%98%E5%A6%82%E6%9E%9Cstore%E9%87%8C%E6%9C%89100%E4%B8%AA%E6%96%B9%E6%B3%95%E9%82%A3%E5%9C%A8%E6%AF%8F%E4%B8%AA%E5%AD%90%E7%BB%84%E4%BB%B6%E7%9A%84-methods%E9%87%8C%E5%A6%82%E4%B8%8B">问题:如果store里有100个方法,那在每个子组件的 methods里如下</h3>
<pre class="hljs"><code><div>methods: {
  add() {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.$store.commit(<span class="hljs-string">'increment'</span>)
  },
  saveOne() {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.$store.commit(<span class="hljs-string">'saveOne'</span>)
  },
  saveTwo() {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.$store.commit(<span class="hljs-string">'saveTwo'</span>)
  },
  saveThree() {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.$store.commit(<span class="hljs-string">'saveThree'</span>)
  }
}
</div></code></pre>
<h3 id="mapmutations%E6%9D%A5%E8%A7%A3%E5%86%B3">mapMutations来解决</h3>
<pre class="hljs"><code><div><span class="hljs-keyword">import</span> { mapMutations } <span class="hljs-keyword">from</span> <span class="hljs-string">'vuex'</span>
</div></code></pre>
<pre class="hljs"><code><div>methods: {
    ...mapMutations({
      increment
    }),
    <span class="hljs-comment">//其它组件自己的方法</span>
}
</div></code></pre>
<blockquote>
<p>上面简写</p>
</blockquote>
<pre class="hljs"><code><div>methods: {
    ...mapMutations({
      <span class="hljs-attr">increment</span>:<span class="hljs-string">'increment'</span>
    })
}
</div></code></pre>
<h2 id="%E5%A6%82%E9%9C%80%E5%8F%98%E6%8D%A2%E5%90%8D%E5%AD%97-%E5%B0%86increment%E6%98%A0%E5%B0%84%E6%88%90%E8%AF%A5%E7%BB%84%E4%BB%B6%E7%9A%84add%E6%96%B9%E6%B3%95">如需变换名字  将increment映射成该组件的add方法</h2>
<pre class="hljs"><code><div>methods: {
    ...mapMutations({
      <span class="hljs-attr">add</span>:<span class="hljs-string">'increment'</span>
    })
}
</div></code></pre>
<h3 id="%E9%97%AE%E9%A2%98mutation-%E5%BF%85%E9%A1%BB%E6%98%AF%E5%90%8C%E6%AD%A5%E5%87%BD%E6%95%B0-mutation-%E5%BF%85%E9%A1%BB%E6%98%AF%E5%90%8C%E6%AD%A5%E5%87%BD%E6%95%B0-mutation-%E5%BF%85%E9%A1%BB%E6%98%AF%E5%90%8C%E6%AD%A5%E5%87%BD%E6%95%B0-%E9%87%8D%E8%A6%81%E9%97%AE%E9%A2%98%E8%AF%B4%E4%B8%89%E9%81%8D">问题:Mutation 必须是同步函数　　mutation 必须是同步函数　　mutation 必须是同步函数　　重要问题说三遍</h3>
<h2 id="%E8%A7%A3%E5%86%B3-action-%E6%89%80%E6%9C%89store%E5%8F%98%E6%9B%B4-%E9%83%BD%E8%B5%B0action">解决  Action  所有store变更 都走action</h2>
<pre class="hljs"><code><div><span class="hljs-keyword">const</span> store = <span class="hljs-keyword">new</span> Vuex.Store({
  <span class="hljs-attr">state</span>: {
    <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>
  },
  <span class="hljs-attr">mutations</span>: {
    increment (state) {
      state.count++
    }
  },
  <span class="hljs-attr">actions</span>: {
    increment (context) {
      context.commit(<span class="hljs-string">'increment'</span>)
    }
  }
})
</div></code></pre>

</body>
</html>
